package com.koo.modules.quartz.util;

import com.koo.common.utils.MyDateUtil;
import com.koo.common.utils.MyStrUtil;
import com.koo.common.utils.secret.AESUtil;
import com.koo.framework.config.ThirdPropFileConfig;
import com.koo.framework.query.MyBatisPlusUtil;
import com.koo.modules.b2b.dao.B2bCompanyInfoDao;
import com.koo.modules.b2b.entity.B2bCompanyInfoEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 改变ResultSet到对象或者集合
 *
 * @author charlin
 */
@Component
@Slf4j
public class ChangeUtil {

    private static B2bCompanyInfoDao b2bCompanyInfoDao;

    @Autowired
    public void setB2bCompanyInfoMapper(B2bCompanyInfoDao b2bCompanyInfoDao) {
        ChangeUtil.b2bCompanyInfoDao = b2bCompanyInfoDao;
    }

    public static <T> List<T> changeResultToList(ResultSet rs, Class<T> clazz) {
        try {
            ResultSetMetaData metaData = rs.getMetaData();
            int columnCount = metaData.getColumnCount();
            rs.last();
            List<T> list = new ArrayList<>(rs.getRow());
            rs.beforeFirst();
            while (rs.next()) {
                T t = clazz.newInstance();
                for (int i = 1; i <= columnCount; i++) {
                    String columnName = metaData.getColumnLabel(i);
                    try {
                        Field field = clazz.getDeclaredField(columnName);
                        field.setAccessible(true);
                        Object columnValue = rs.getObject(i);
                        String type = field.getGenericType().getTypeName();//getTypeName没有class,toString有
                        if (type.equals("java.lang.String")) {
                            if (columnValue instanceof Date) {
                                // 存在BigDecimal的情况
                                Timestamp tempDate = (Timestamp) columnValue;
                                columnValue = tempDate.toString() + "";
                            } else if (columnValue instanceof BigDecimal) {
                                BigDecimal bigdecimal = (BigDecimal) columnValue;
                                columnValue = bigdecimal.toString();
                            } else if (columnValue instanceof Integer) {
                                columnValue = columnValue.toString();
                            }
                            field.set(t, columnValue);
                        } else if (type.equals("java.lang.Integer")) {
                            Integer value = null;
                            if (columnValue != null) {
                                if (columnValue.equals(false) || columnValue.equals(0)) {
                                    value = 0;
                                } else if (columnValue.equals(true) || columnValue.equals(1)) {
                                    value = 1;
                                } else if (columnValue instanceof BigDecimal) {
                                    // 存在BigDecimal的情况
                                    BigDecimal bigdecimal = (BigDecimal) columnValue;
                                    value = bigdecimal.intValue();
                                } else if (columnValue instanceof Integer) {
                                    value = (Integer) columnValue;
                                }
                            }
                            field.set(t, value);
                        } else if (type.equals("java.math.BigDecimal")) {
                            BigDecimal value = null;
                            if (columnValue instanceof String) {
                                value = new BigDecimal(((String) columnValue).trim());
                            } else {
                                value = (BigDecimal) columnValue;
                            }
                            field.set(t, value);
                        } else if (type.equals("java.util.Date")) {
                            Date value = null;
                            if (columnValue instanceof String || columnValue instanceof Date) {
                                value = MyDateUtil.parseDateByAuto(columnValue.toString());
                            }
                            field.set(t, value);
                        } else {
                            field.set(t, columnValue);
                        }
                    } catch (SecurityException | IllegalArgumentException | IllegalAccessException e) {
                        log.error(e.getMessage(), e);
                    } catch (NoSuchFieldException e2) {
                        e2.printStackTrace();
                    }
                }
                list.add(t);
            }
            return list;
        } catch (SQLException | InstantiationException | IllegalAccessException e1) {
            e1.printStackTrace();
        }
        return new ArrayList<>();
    }

    /**
     * 根据前缀,查询该供应商是否需要进行数据同步.
     *
     * @param code
     * @return
     */
    public static boolean checkNeedThridDataService(String code) {
        if (!"true".equals(ThirdPropFileConfig.getProperty("runSync_" + code))) {
            return false;
        }
        B2bCompanyInfoEntity info = new B2bCompanyInfoEntity();
        info.setCompanyCode(code);
        info.setStatus(1);
        Integer selectCount = b2bCompanyInfoDao.selectCount(MyBatisPlusUtil.createEQWrapper(info, "companyCode", "status"));
        if (MyStrUtil.isEmpty(selectCount) || selectCount.equals(0)) {
            return false;
        }
        return true;
    }

    public static String decryptValue(String encryptionValue) {
        if (MyStrUtil.isNotEmpty(encryptionValue) && encryptionValue.length() >= 32 && MyStrUtil.isUpperCase(encryptionValue) && "true".equals(ThirdPropFileConfig.getProperty("encrypt"))) {
            encryptionValue = AESUtil.decrypt(encryptionValue);
        }
        return encryptionValue;
    }
}
